/*
//  Copyright © 2014 Allen County Public Library.

  //        ACPL Mobile is free software: This program is distributed and you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.  ACPL Mobile is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, including without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ACPL Mobile. If not, see http://www.gnu.org/licenses/.
 * Author: James Harpe
 * 
 * Description: This class is a superclass for catalog searching.
 * 
 */

package us.in.lib.acpl.Mobile_ACPL.ws;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;
import us.in.lib.acpl.Mobile_ACPL.SearchResultsActivity;
import us.in.lib.acpl.Mobile_ACPL.context.Mobile_ACPL;
import us.in.lib.acpl.Mobile_ACPL.item.SearchResultTitle;
import us.in.lib.acpl.Mobile_ACPL.util.RestClient;
import us.in.lib.acpl.Mobile_ACPL.util.RestClient.RequestMethod;

public abstract class SearchCatalogHandler {
	public static final String SEARCH_CATALOG_URL = Mobile_ACPL.WS_HOST+"/symws/rest/standard/searchCatalog";
	public static final String SEARCH_CATALOG_PAGING_URL = Mobile_ACPL.WS_HOST+"/symws/rest/standard/searchCatalogPaging";
	protected String queryID;
	protected long totalResults;
	protected List<SearchResultTitle> results;
	protected String term;
	protected int pageToGet;
	protected String materialTypeFilter;

	public static final int RESULTS_PER_PAGE = 20;
    //ACPL: Removed Sirsi Client id
	public static final String CLIENT_ID = "";

	public SearchCatalogHandler() {
		queryID = null;
		pageToGet = 1;
		totalResults = 0;
		results = null;
	}

	public abstract void search(String term, int resultsPerPage,
			String searchTypeFilter, String searchLibraryFilter,
			String materialTypeFilter);

	public abstract void getMoreResults(SearchResultsActivity act);

	public abstract String getTerm();

	public abstract void setTerm(String term);

	public abstract void setQueryID(String id);

	public abstract void displaySearchResults(List<SearchResultTitle> list);

	public abstract String getQueryID();

	public abstract List<SearchResultTitle> getResults();

	public abstract void setResults(List<SearchResultTitle> results);

	public abstract long getTotalResults();

	public abstract void setTotalResults(long totalResults);

	public abstract boolean hasMoreResults();

	public String doSearchCatalogRequest(String searchTerm,
			String searchTypeFilter, String searchLibraryFilter) {

		RestClient client = new RestClient(SEARCH_CATALOG_URL);
		client.AddHeader("x-sirs-clientID", CLIENT_ID);
		client.AddParam("term1", searchTerm);
		client.AddParam("includeAvailabilityInfo", "true");

		if (searchTypeFilter != null) {
			client.AddParam("searchType1", searchTypeFilter);
		}

		if (searchLibraryFilter != null) {
			client.AddParam("libraryFilter", searchLibraryFilter);
		}

		try {
			client.Execute(RequestMethod.POST);
		} catch (Exception e) {

			e.printStackTrace();
		}

		String response = client.getResponse();

		return response;
	}

	public String doGetMoreResults() {
		pageToGet = pageToGet + 1;

		int firstResult = RESULTS_PER_PAGE * (pageToGet - 1) + 1;

		int lastResult = firstResult + (RESULTS_PER_PAGE - 1);

		if (lastResult >= totalResults) {
			lastResult = (int) totalResults;
		}

		RestClient client = new RestClient(SEARCH_CATALOG_PAGING_URL);
		client.AddHeader("x-sirs-clientID", CLIENT_ID);
		client.AddParam("queryID", queryID);
		client.AddParam("firstHitToDisplay", String.valueOf(firstResult));
		client.AddParam("lastHitToDisplay", String.valueOf(lastResult));
		client.AddParam("includeAvailabilityInfo", "true");

		try {
			client.Execute(RequestMethod.POST);
		} catch (Exception e) {
			e.printStackTrace();
		}

		String response = client.getResponse();

		return response;
	}

	public List<SearchResultTitle> parseResponse(String toParse)
			throws XmlPullParserException, IOException {
		ArrayList<SearchResultTitle> list = new ArrayList<SearchResultTitle>();
		if (toParse == null) {

			return null;
		}
		try {

			SearchResultTitle currentTitle = new SearchResultTitle();

			ArrayList<String> librariesWithAvailableCopies = new ArrayList<String>();
			ArrayList<String> isbn = new ArrayList<String>();

			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(new StringReader(toParse));

			int eventType = parser.getEventType();
			boolean keepOut = false;
			while (eventType != XmlPullParser.END_DOCUMENT) {
				if (eventType == XmlPullParser.START_TAG) {
					String name = parser.getName();
					if (name.equalsIgnoreCase("message")) {
						String text = parser.nextText();
						if (text.equalsIgnoreCase("Unavailable for display")) {
							keepOut = true;
						}
					}
					if (name.equalsIgnoreCase("queryID")) {

						queryID = parser.nextText();

					}
					if (name.equalsIgnoreCase("totalHits")) {
						totalResults = Long.parseLong(parser.nextText());

					}
					if (name.equalsIgnoreCase("titleID")) {
						currentTitle.setTitleID(parser.nextText());
					}
					if (name.equalsIgnoreCase("libraryWithAvailableCopies")) {
						librariesWithAvailableCopies.add(parser.nextText());
					}
					if (name.equalsIgnoreCase("totalCopiesAvailable")) {
						currentTitle.setTotalCopiesAvailable(parser.nextText());
					}
					if (name.equalsIgnoreCase("locationOfFirstAvailableCopy")) {
						currentTitle.setLocationOfFirstAvailableItem(parser
								.nextText());
					}
					if (name.equalsIgnoreCase("holdable")) {
						currentTitle.setHoldable(Boolean.parseBoolean(parser
								.nextText()));
					}
					if (name.equalsIgnoreCase("materialType")) {
						currentTitle.setMaterialType(parser.nextText());
					}
					if (name.equalsIgnoreCase("title")) {
						currentTitle.setTitle(parser.nextText());
					}
					if (name.equalsIgnoreCase("author")) {
						currentTitle.setAuthor(parser.nextText());
					}
					if (name.equalsIgnoreCase("yearOfPublication")) {
						currentTitle.setYearOfPublication(parser.nextText());
					}
					if (name.equalsIgnoreCase("edition")) {
						currentTitle.setEdition(parser.nextText());
					}
					if (name.equalsIgnoreCase("isbn")) {
						isbn.add(parser.nextText());
					}
					if (name.equalsIgnoreCase("callNumber")) {
						currentTitle.setCallNumber(parser.nextText());
					}
					if (name.equalsIgnoreCase("url")) {
						currentTitle.setUrl(parser.nextText());
					}
				}

				if (eventType == XmlPullParser.END_TAG) {
					if (parser.getName().equalsIgnoreCase("HitlistTitleInfo")) {
						currentTitle
								.setLibrariesWithAvailableCopies(librariesWithAvailableCopies
										.toArray(new String[0]));
						librariesWithAvailableCopies = new ArrayList<String>();

						currentTitle.setIsbn(isbn.toArray(new String[0]));
						isbn = new ArrayList<String>();

						if (!keepOut) {
							list.add(currentTitle);
						}
						keepOut = false;
						currentTitle = new SearchResultTitle();
					}
				}
				eventType = parser.next();
			}

		} catch (XmlPullParserException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}

		if (materialTypeFilter != null) {
			ArrayList<SearchResultTitle> toRemove = new ArrayList<SearchResultTitle>();
			if (materialTypeFilter.equalsIgnoreCase("Book")) {
				for (SearchResultTitle title : list) {
					if (!(title.getMaterialType().equalsIgnoreCase("Book")
							|| title.getMaterialType().equalsIgnoreCase("CR") || title
							.getMaterialType().equalsIgnoreCase("MUSIC"))) {
						toRemove.add(title);
					}
				}

			} else if (materialTypeFilter.equalsIgnoreCase("Music")) {
				for (SearchResultTitle title : list) {
					if (!(title.getMaterialType().equalsIgnoreCase("SOUNDDISC") || title
							.getMaterialType().equalsIgnoreCase("SOUNDCASS"))) {
						toRemove.add(title);
					}
				}
			} else if (materialTypeFilter.equalsIgnoreCase("Video")) {
				for (SearchResultTitle title : list) {
					if (!(title.getMaterialType().equalsIgnoreCase("VIDEODISC") || title
							.getMaterialType().equalsIgnoreCase("VIDEOCASS"))) {
						toRemove.add(title);
					}
				}
			}

			list.removeAll(toRemove);
		}

		return list;
	}

}
